﻿using AuthCenter.CSM.Common;
using AuthCenter.CSM.Dto;
using AuthCenter.Data.Database;
using AuthCenter.Token;
using AuthCenter.Tools.Password;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TouchSocket.Core;
using TouchSocket.Http;

namespace AuthCenter.CSM.plugins
{
    internal class SignPlug : AuthCenterPluginBase
    {
        protected override string ListenUri { get; } = HttpCommon.SiteName+"/sign";
        protected override async Task OnRequest(AuthCenterSession session)
        {
            if (session.IsPost(HttpCommon.SiteName+"/sign"))
            {
                var data = await session.GetData<AuthCenterInput>();

                var output = new AuthCenterOutput();
                output.Success = true;
                string? pass;
                if (session.AppID == Guid.Empty)
                {
                    output.Success = false;
                }
                if (string.IsNullOrEmpty(session.DeviceName))
                {
                    output.Success = false;
                }


                if (output.Success) switch (data.Method)
                    {
                        case "login":
                            var userId = session.db_auth.GetUserID(data.Params["user"]);
                            if (userId == Guid.Empty)
                            {
                                //没有这个用户
                                output.Success = false;
                            }
                            else
                            {
                                //登录
                                pass = session.db_auth.GetUserPass(userId);
                                if (string.IsNullOrEmpty(pass))
                                {
                                    output.Success = false;
                                }else
                                if (data.GetText("pass") == pass)
                                {
                                    //验证是否有权限访问应用
                                    if (session.db_auth.AppIsAuthUser(userId, session.AppID))
                                    {
                                        // 1.生成/获取Device
                                        var deviceId = session.db_device.MakeDevice(userId, session.IP, session.DeviceName);
                                        var tokenKey = session.db_device.GetTokenKey(deviceId, session.AppID);
                                        if (!string.IsNullOrEmpty(tokenKey.Secret))
                                        {
                                            var token = GlobalToken.Make(tokenKey.OnlineID, userId, tokenKey.Secret);
                                            output.Params["token"] = $"{token}";
                                            output.Params["oid"] = $"{tokenKey.OnlineID}";
                                        }
                                        else
                                        {
                                            output.Success = false;
                                        }
                                    }
                                    else
                                    {
                                        output.Success = false;
                                    }
                                }
                                else
                                {
                                    output.Success = false;
                                }
                            }
                            if (output.Success)
                            {
                                session.db_log.Record("login", $"{session.IP} 成功登录", session.AppID, userId);
                            }
                            else
                            {
                                session.db_log.RecordError("login", $"{session.IP} 登录失败", session.AppID, userId);
                            }
                            break;
                        case "usercode":
                            var userId_c = session.db_auth.GetUserID(data.Params["user"]);
                            if (userId_c == Guid.Empty)
                            {
                                //没有这个用户
                                output.Success = false;
                            }
                            else
                            {
                                //用户码
                                pass = session.db_auth.GetUserPass(userId_c);
                                if (pass == null)
                                {
                                    output.Success = false;
                                }
                                else
                                {
                                    output.Params["user-code"] = PasswordCode.ReadCode(pass);
                                    output.Params["user-type"] = PasswordVersion.ReadVersionTag(pass);
                                }
                            }
                            break;
                        case "usernextcode":
                            if (session.IsAuthenticated)
                            {
                                //用户码
                                pass = session.db_auth.GetUserNextPass(session.UserID);
                                output.Params["user-code"] = PasswordCode.ReadCode(pass);
                                output.Params["user-type"] = PasswordVersion.ReadVersionTag(pass);
                            }
                            else
                            {
                                output.Success = false;
                            }
                            break;
                        case "change-password":
                            //密码修改
                            if (session.IsAuthenticated)
                            {
                                var pwd = data.Params["password"];
                                var pwd_new = data.Params["passwordnew"];

                                var pwd1 = session.db_auth.GetUserPass(session.UserID);
                                if(pwd1 == null)
                                {
                                    output.Success = false;
                                }
                                else
                                {
                                    var pwd2 = session.db_auth.GetUserNextPass(session.UserID);
                                    var c1 = PasswordCode.ReadCode(pwd1);
                                    var v1 = PasswordVersion.ReadVersionTag(pwd1);
                                    var c2 = PasswordCode.ReadCode(pwd2);
                                    var v2 = PasswordVersion.ReadVersionTag(pwd2);
                                    if (PasswordFactory.Make(pwd, c1, v1) == pwd1 && PasswordFactory.Make(pwd, c2, v2) == pwd2)
                                    {
                                        //认证通过
                                        session.db_auth.UpdateUserPassword(session.UserID, pwd_new);
                                    }
                                    else
                                    {
                                        output.Success = false;
                                    }
                                }
                            }
                            else
                            {
                                output.Success = false;
                            }

                            if (output.Success)
                            {
                                session.db_log.Record("change-password", $"{session.IP} 修改成功", session.AppID, session.UserID);
                            }
                            else
                            {
                                session.db_log.RecordError("change-password", $"{session.IP} 修改失败", session.AppID, session.UserID);
                            }
                            break;
                        default:
                            output.Success = false;
                            break;
                    }

                await session.Send(200, output)
                        .AnswerAsync();//直接回应
            }

            //无法处理，调用下一个插件
            await session.InvokeNext();
        }
    }
}
